home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
xcoral
/
xcoral.lha
/
xcoral-1.72
/
handle_menus.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-23
|
13KB
|
500 lines
/*
** Copyright 1989, 1992 by Lionel Fournigault
**
** Permission to use, copy, and distribute for non-commercial purposes,
** is hereby granted without fee, providing that the above copyright
** notice appear in all copies and that both the copyright notice and this
** permission notice appear in supporting documentation.
** The software may be modified for your own purposes, but modified versions
** may not be distributed.
** This software is provided "as is" without any expressed or implied warranty.
**
**
*/
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "menus.h"
extern XContext SwContext;
static int button_press;
static Window HandleButtonReleaseMenu ();
static void HandleExposeMenu (), HandleLeaveMenu (), HandleEnterMenu ();
static void clear_item (), show_item (), clear_menu (), show_menu ();
extern void Display3D ();
/*
** Function name : HandleMenu
**
** Description : Point d'entree dans la gestion des menus apres un ButtonPress
**
** Input : Le display, structure event, la fenetre parent, le menu courant,
** le numero du menu, les infos pour la callback.
** Ouput : La fenetre du ButtonRelease.
*/
Window HandleMenu ( display, ev, frame, menu, n, vm, item )
Display *display;
XButtonPressedEvent *ev;
Window frame;
XYMenu *menu;
register int n;
register int *vm, *item; /* RETURN */
{
XEvent event;
SWindow *sw;
int pointer_in, last;
button_press = ev -> button;
XGrabPointer ( display, frame, True, ButtonPressMask
| ButtonReleaseMask, GrabModeAsync,
GrabModeAsync, frame, None , CurrentTime);
show_menu ( display, menu, n );
menu -> w_last_item = 0;
menu -> n_last_item = -1;
pointer_in = True;
for (;;) {
XNextEvent ( display, &event );
switch ( event.type ) {
case EnterNotify:
HandleEnterMenu ( display,
(XEnterWindowEvent *) &event,
menu, (SWindow *) &sw, &pointer_in );
break;
case LeaveNotify:
HandleLeaveMenu ( display,
(XLeaveWindowEvent *) &event,
menu, &pointer_in );
break;
case Expose:
HandleExposeMenu ( display,
(XExposeEvent *) &event,
menu, &last );
break;
case ButtonRelease:
if ( button_press != event.xbutton.button )
break;
XUngrabPointer ( display, CurrentTime );
if ( HandleButtonReleaseMenu ( display,
(XButtonReleasedEvent *) &event,
menu, frame, vm, item ) ) {
return ( event.xany.window );
}
else {
return 0;
}
}
}
}
/*
** Function name : HandleButtonReleaseMenu
**
** Description : Traitement de l'evennement ButtonRelease
**
** Input : Le display, button event, le menu, la fenetre parent
** les infos sur la callback.
** Ouput : La fenetre de l'evennement,
*/
static Window HandleButtonReleaseMenu ( display, ev, menu, frame, vm, it )
Display *display;
XButtonReleasedEvent *ev;
XYMenu *menu;
Window frame;
register int *vm, *it; /* RETURN */
{
register int last = menu -> n_last_mapped;
register int item = menu -> n_last_item;
#ifdef DEBUG
( void ) fprintf ( stderr, "HandleButtonRelease w = %d\n",
ev -> window );
#endif
if ( DoesSaveUnders ( DefaultScreenOfDisplay ( display )) != True )
menu -> save_ok = 0; /* Pour reinitialiser */
if ( menu -> mapped != 0 ) {
clear_menu ( display, menu, last );
XSync ( display, True );
if ( DoesSaveUnders ( DefaultScreenOfDisplay ( display )) != True )
XCopyArea ( display, menu -> save, menu -> w_under,
menu -> Ugc, 0, 0, menu -> pix_width,
#ifdef SHADOW
menu -> hmax_menu + SHAD + 10,
#else
menu -> hmax_menu + 10,
#endif
0, 0 );
if ( item != -1 ) {
*vm = last;
*it = item;
}
else {
*vm = *it = -1;
}
}
if ( ev -> window != frame
&& ev -> window != menu -> mapped
&& ev -> window != menu -> w_title [last] ) {
#ifdef DEBUG
( void ) fprintf ( stderr, "\tNot Parent\n" );
#endif
return ( ev -> window );
}
else
return 0;
}
/*
** Function name : HandleExposeMenu
**
** Description : Traite les evenements d'exposition pendant
** le ButtonPress et gere l'affichage des menus.
**
** Input : Le display, l'expose event, le menu, dernier menu expose
** Ouput :
*/
static void HandleExposeMenu ( display, ev, menu, last )
Display *display;
XExposeEvent *ev;
XYMenu *menu;
int *last;
{
register char **str;
register int i;
XRectangle rec [2];
#ifdef DEBUG
( void ) fprintf ( stderr, "HandleExpose w = %d\n",
ev -> window );
#endif
*last = menu -> n_last_mapped;
str = menu -> vmenu [*last] -> iname;
/*
if ( ev -> window == menu -> vmenu [*last] -> v_frame ) {
}
*/
for ( i=0; i < menu->vmenu [*last]->nb_items; i++ ) {
if ( ev -> window == menu -> vmenu [*last] -> w_item [i] ) {
XDrawString ( display,
menu -> vmenu [*last] -> w_item [i],
menu->Ngc, 10,
menu -> y_title + menu -> width_relief,
*str,strlen ( *str ));
Display3D ( display,
menu -> vmenu [*last] -> w_item [i],
menu -> top_sh, menu -> bot_sh,
menu -> width_relief,
DEPTH_UP );
return;
}
str++;
}
if ( DoesSaveUnders ( DefaultScreenOfDisplay ( display )) == True )
return;
if ( ev -> window == menu -> w_under ) {
rec [0].x = ev -> x;
rec [0].y = ev -> y;
rec [0].width = ev -> width;
rec [0].height = ev -> height;
XSetClipRectangles ( display, menu -> Ugc, 0,0,
rec, 1, Unsorted );
XCopyArea ( display, menu -> save, menu -> w_under,
menu -> Ugc, 0, 0, menu -> pix_width,
#ifdef SHADOW
menu -> hmax_menu + SHAD + 10,
#else
menu -> hmax_menu,
#endif
0, 0 );
XSetClipMask ( display, menu -> Ugc, None );
}
}
/*
** Function name : HandleLeaveMenu
**
** Description : Traite les evenements LeaveNotify pendant
** le ButtonPress et gere l'affichage des menus.
**
** Input : Le Display, l'evenement, le menu et nn flag qui indique
** si on est ou non dans la fenetre courante.
** Ouput :
*/
static void HandleLeaveMenu ( display, ev, menu, p_in )
Display *display;
XLeaveWindowEvent *ev;
XYMenu *menu;
int *p_in;
{
XWindowAttributes att;
#ifdef DEBUG
(void) fprintf ( stderr, "HandleLeave w = %d\n", ev -> window );
#endif
if ( ev -> mode == NotifyGrab ) return;
if ( (ev -> window == menu -> mapped) ||
(ev -> window == menu -> vmenu [ menu -> n_last_mapped ] -> v_frame) ) {
clear_item ( display, menu,
menu -> n_last_mapped );
}
if ( ev -> window == menu -> parent ) {
#ifdef DEBUG
( void ) fprintf ( stderr, "\t Leave environnement... pas sur.\n" );
( void ) fprintf ( stderr, "x = %d y = %d", ev -> x, ev -> y );
#endif
XGetWindowAttributes ( display, menu -> parent, &att );
#ifdef DEBUG
( void ) fprintf ( stderr, "width = %d height = %d", att.width, att.height );
#endif
if ( ev -> x < 0 || ev -> y < 0
|| ev -> x > att.width || ev -> y > att.height )
*p_in = False;
}
}
/*
** Function name : HandleEnterMenu
**
** Description : Traite les evenements EnterNotify pendant
** le ButtonPress et gere l'affichage des menus.
**
** Input : Le display, l'evenement, le menu courant,
** le contexte courant ( quel menu et quel item sont mappes ),
** un flag qui indique si on est ou non dans la fenetre courante.
** Ouput :
*/
static void HandleEnterMenu ( display, ev, menu, sw, p_in )
Display *display;
XEnterWindowEvent *ev;
XYMenu *menu;
SWindow *sw;
int *p_in;
{
register int i;
#ifdef DEBUG
(void) fprintf ( stderr, "HandleEnter w = %d\n", ev -> window );
#endif
/*
* On verifie que le pointer est sur les menus courants.
*/
*p_in = False;
for ( i=0;i<MAX_MENUS;i++ ) {
if ( ev -> window == menu -> w_title [i] ) {
*p_in = True;
break;
}
}
for ( i=0;i<MAX_ITEMS;i++ ) {
if ( *p_in == True ) break;
if ( ev -> window ==
menu -> vmenu [ menu -> n_last_mapped ] -> w_item [i] ) {
*p_in = True;
break;
}
}
if ( ev -> mode == NotifyGrab || *p_in == False )
return;
if ( XFindContext ( display, ev -> window, SwContext, (caddr_t *) &sw ) != 0 ) {
#ifdef DEBUG
( void ) fprintf ( stderr, "HandleEnter XFind default\n" );
#endif
}
switch ( sw -> type ) {
case MENU :
if ( menu -> n_last_mapped != sw -> no_m )
show_menu ( display, menu, sw -> no_m );
break;
case ITEM :
show_item ( display, menu, sw -> no_i, sw -> no_m );
break;
default:
#ifdef DEBUG
(void ) fprintf ( stderr,"HandleEnter CaseDefault\n" );
#endif
break;
}
return;
}
/*
** Function name : clear_item
**
** Description : Efface l'item allume du menu n.
**
** Input : Le display, le menu courant et son numero.
** Ouput :
*/
static void clear_item ( display, menu, n )
Display *display;
XYMenu *menu;
register int n;
{
if ( menu -> w_last_item == 0 ) return;
if ( DefaultDepth ( display, DefaultScreen ( display )) == 1 )
XFillRectangle ( display,
menu -> w_last_item,
menu -> Igc,
0 + menu -> width_relief,
0 + menu -> width_relief,
menu -> vmenu [n] -> width - ( 2 * menu -> width_relief ) - 6,
menu -> h_item - ( 2 * menu -> width_relief ));
else
Display3D ( display, menu -> w_last_item,
menu -> top_sh, menu -> bot_sh,
menu -> width_relief,
DEPTH_UP );
menu -> w_last_item = 0;
menu -> n_last_item = -1;
}
/*
** Function name : show_item
**
** Description : Affiche l' item i du menu n.
**
** Input : Le display, le menu courant, l'item et le no du menu.
** Ouput :
*/
static void show_item ( display, menu, i, n )
Display *display;
XYMenu *menu;
register int i, n;
{
if ( DefaultDepth ( display, DefaultScreen ( display )) == 1 )
XFillRectangle ( display,
menu -> vmenu [n] -> w_item [i],
menu -> Igc,
0 + menu -> width_relief,
0 + menu -> width_relief,
menu -> vmenu [n] -> width - ( 2 * menu -> width_relief ) - 6,
menu -> h_item - ( 2 * menu -> width_relief )) ;
else
Display3D ( display, menu -> vmenu [n] -> w_item [i],
menu -> top_sh, menu -> bot_sh,
menu -> width_relief,
DEPTH_DOWN );
if ( menu -> w_last_item != 0 )
if ( DefaultDepth ( display, DefaultScreen ( display )) == 1 )
XFillRectangle ( display,
menu -> w_last_item,
menu -> Igc,
0 + menu -> width_relief,
0 + menu -> width_relief,
menu -> vmenu [n] -> width - ( 2 * menu -> width_relief ) - 6,
menu -> h_item - ( 2 * menu -> width_relief ));
else
Display3D ( display, menu -> w_last_item,
menu -> top_sh, menu -> bot_sh,
menu -> width_relief,
DEPTH_UP );
menu -> w_last_item = menu -> vmenu [n] -> w_item [i];
menu -> n_last_item = i;
}
/*
** Function name : clear_menu
**
** Description : Efface le menu n.
**
** Input : Le display, le menu courant, son numero.
** Ouput :
*/
static void clear_menu ( display, menu, n )
Display *display;
XYMenu *menu;
register int n;
{
if ( DefaultDepth ( display, DefaultScreen ( display )) == 1 )
XFillRectangle ( display, menu->w_title [n], menu->Igc,
0 + menu -> width_relief,
0 + menu -> width_relief,
menu->title_width [n] - ( 2 * menu -> width_relief ),
menu -> h_item - ( 2 * menu -> width_relief ));
#ifdef SHADOW
XUnmapWindow ( display, menu->vmenu [n] -> trans );
#else
XUnmapWindow ( display, menu->vmenu [n]->v_frame );
#endif
menu -> mapped = 0;
menu -> w_last_item = 0;
menu -> n_last_item = -1;
menu -> n_last_unmapped = n;
XFlush ( display );
}
/*
** Function name : show_menu
**
** Description : Affiche le menu n.
**
** Input : Le Dispaly, le contexte de menu et le numero du menu.
** Ouput :
*/
static void show_menu ( display, menu, n )
Display *display;
XYMenu *menu;
register int n;
{
register int last = menu -> n_last_mapped;
if ( menu -> mapped != 0 ) {
clear_menu ( display, menu, last );
menu -> w_last_item = 0;
menu -> n_last_item = -1;
}
#ifdef DEBUG
(void) fprintf ( stderr, "Show_menu : Menu : %d, width = %d\n",
n, menu -> title_width [n] );
#endif
if ( DefaultDepth ( display, DefaultScreen ( display )) == 1 )
XFillRectangle ( display, menu -> w_title [n],
menu -> Igc,
0 + menu -> width_relief,
0 + menu -> width_relief,
menu -> title_width [n] - ( 2 * menu -> width_relief ),
menu -> h_item - ( 2 * menu -> width_relief ));
if ( DoesSaveUnders ( DefaultScreenOfDisplay ( display )) != True ) {
if ( menu -> save_ok == 0 ) {
XCopyArea ( display, menu -> w_under,
menu -> save, menu -> Ugc,
0, 0,menu -> pix_width,
#ifdef SHADOW
menu -> hmax_menu + SHAD + 10,
#else
menu -> hmax_menu + 10,
#endif
0, 0 );
menu -> save_ok = 1; /* La pixmap est pleine */
}
}
#ifdef SHADOW
XMapRaised ( display, menu->vmenu [n] -> trans );
#else
XMapRaised ( display, menu->vmenu [n]->v_frame );
#endif
#ifdef SHADOW
menu->mapped = menu->vmenu [n] -> trans;
#else
menu->mapped = menu->vmenu [n] -> v_frame;
#endif
menu -> n_last_mapped = n;
}